"""
Case Type   : 资源池化故障模式库
Case Name   : 删除已存在的配置项-清空配置文件
Create At   : 2025/04
Owner       : haomeng
Description :
    1、查看集群状态
    2、运行tpcc业务
    3、清空主节点配置文件内容
    4、查看业务运行情况
    5、重启集群
    6、恢复原postgresql.conf配置文件
    7、拉起被踢出节点
    8、查看集群状态
Expect      :
    1、集群状态正常
    2、运行业务成功
    3、清空主节点postgresql.conf配置文件成功
    4、业务运行正常无影响
    5、重启集群失败，原主节点被踢出
    6、恢复原postgresql.conf文件成功
    7、启动集群成功
    8、集群状态正常
History     :
"""

import os
import time
import unittest

from testcase.utils.Common import Common
from testcase.utils.CommonSH import CommonSH
from testcase.utils.ComThread import ComThread
from testcase.utils.Constant import Constant
from testcase.utils.Logger import Logger
from yat.test import Node
from yat.test import macro

class SSFauleMode(unittest.TestCase):

    def setUp(self):
        self.log = Logger()
        self.log.info(f'----{os.path.basename(__file__)} start----')
        self.user_node = [Node(node='PrimaryRoot'), Node(node='PrimaryDbUser')]
        self.pri_sh = CommonSH('PrimaryDbUser')
        self.com = Common()
        self.constant = Constant()
        self.conf_file = os.path.join(macro.DB_INSTANCE_PATH, macro.DB_PG_CONFIG_NAME)

    def test_ss_faule(self):
        text = '-----step1:查看集群状态;  expect:集群状态正常-----'
        self.log.info(text)

        status = self.pri_sh.exec_cm_ctl('query', '-Cv')
        self.log.info(status)
        self.assertIn('Normal', status, '集群状态异常')

        text = '-----step2:执行tpcc读写业务  expect:业务执行成功-----'
        self.log.info(text)

        tpcc_cmd = f'./runBenchmark.sh {macro.PROPS_FILENAME}'
        self.log.info(tpcc_cmd)

        tpcc_execute = ComThread(self.com.start_tpcc, args=(self.user_node[0],
                                                               f'{macro.TPCC_PATH}',
                                                               tpcc_cmd))
        tpcc_execute.setDaemon(True)
        tpcc_execute.start()

        text = '-----step3:清空主节点postgresql.conf文件  expect:清空成功-----'
        self.log.info(text)

        delete = f'cp {self.conf_file} {self.conf_file}_bakkk;' \
                 f'cat /dev/null > {self.conf_file};'
        self.log.info(delete)

        delete_execute = ComThread(self.com.get_sh_result, args=(self.user_node[1], delete))
        delete_execute.setDaemon(True)
        delete_execute.start()

        text = '-----step4:查看业务运行情况  expect:业务运行正常无影响-----'
        self.log.info(text)

        tpcc_execute.join(10 * 60)
        ret1 = tpcc_execute.get_result()
        self.log.info(ret1)
        self.assertIn('Session End', ret1, 'tpcc执行失败')

        delete_execute.join(10 * 60)
        ret2 = delete_execute.get_result()
        self.log.info(ret2)
        self.assertIn('', ret2, '清空postgresql.conf文件失败')

        text = '-----step5:重启集群  expect:重启失败-----'
        self.log.info(text)

        restart = self.pri_sh.exec_cm_ctl('stop;', 'cm_ctl start -t 30')
        self.log.info(restart)
        self.assertIn(self.constant.cm_stop_success_msg, restart, '重启集群失败')

        time.sleep(60)
        status = self.pri_sh.exec_cm_ctl('query', '-Cv')
        self.log.info(status)
        self.assertNotIn('cluster_state  ：Normal', status, '集群状态正常')
        self.assertIn('S Primary', status, '集群状态异常')

    def tearDown(self):
        text = '-----step6:恢复原postgresql.conf文件  expect:恢复成功-----'
        self.log.info(text)

        mv = f'mv {self.conf_file}_bakkk {self.conf_file};' \
             f'cat {self.conf_file} | grep max_connections;'
        self.log.info(mv)
        mv_execute = self.user_node[1].sh(mv).result()
        self.log.info(mv_execute)

        text = '-----step7:拉起被踢出节点  expect:启动成功-----'
        self.log.info(text)

        start = self.pri_sh.exec_cm_ctl('start')
        self.log.info(start)

        text = '-----step8:查看集群状态  expect:集群状态正常-----'
        self.log.info(text)

        status = self.pri_sh.exec_cm_ctl('query', '-Cv')
        self.log.info(status)

        if 'P Primary' not in status:
            switch = self.pri_sh.exec_cm_ctl('switchover', '-a')
            self.log.info(switch)

        time.sleep(60)
        status = self.pri_sh.exec_cm_ctl('query', '-Cv')
        self.log.info(status)
        self.assertIn('Normal', status, '集群状态异常')
        self.assertIn('P Primary', status.splitlines()[-1], '集群状态异常')
        self.assertIn('max_connections', mv_execute, '恢复配置文件失败')
        self.assertIn(self.constant.cm_start_success_msg, start, '启动集群失败')
        self.log.info(f'----{os.path.basename(__file__)} end----')
